﻿using LJ.Abstractions.DependencyInjection;
using LJ.Abstractions.Extensions;
using LJ.Abstractions.Reflection;
using LJ.StreamSystem.Abstractions;
using LJ.StreamSystem.Abstractions.Attributes;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Concurrent;
using System.Reflection;

namespace LJ.StreamSystem.LazyHare.Internal;

public class StreamSystemManager : IStreamSystemManager
{
    private readonly ConcurrentDictionary<string, AggregateStreamSystemHandlerDescriptor> _aggregateStreamSystemHandlerDescriptors = [];

    private readonly IDependencyManager _dependencyManager;

    private readonly IReflectionManager _reflectionManager;
    public StreamSystemManager(IDependencyManager dependencyManager, IReflectionManager reflectionManager)
    {
        _dependencyManager = dependencyManager;
        _reflectionManager = reflectionManager;


        //查找所有自动注册的服务实现类型进行注册
        var aggregateStreamSystemHandlerTypes = FindAggregateStreamSystemHandlerTypes();
        foreach (Type type in aggregateStreamSystemHandlerTypes)
        {
            var aggregateStreamSystemHandlerAttribute = type.GetCustomAttribute<AggregateStreamSystemHandlerAttribute>();
            if (aggregateStreamSystemHandlerAttribute != null)
            {
                _dependencyManager.ServiceCollection.AddTransient(type);

                var aggregateEventDataType = GetAggregateEventDataType(type);
                var aggregateSummaryEventDataType = GetAggregateSummaryEventDataType(type);

                _aggregateStreamSystemHandlerDescriptors.AddOrUpdate(aggregateStreamSystemHandlerAttribute.ApplicationId,
                    a => new AggregateStreamSystemHandlerDescriptor(aggregateStreamSystemHandlerAttribute.ApplicationId, aggregateStreamSystemHandlerAttribute.AggregateSummaryTopic, 
                    aggregateStreamSystemHandlerAttribute.AggregateTopic, aggregateEventDataType, aggregateSummaryEventDataType, type),
                    (a, b) => new AggregateStreamSystemHandlerDescriptor(aggregateStreamSystemHandlerAttribute.ApplicationId, aggregateStreamSystemHandlerAttribute.AggregateSummaryTopic,
                    aggregateStreamSystemHandlerAttribute.AggregateTopic, aggregateEventDataType, aggregateSummaryEventDataType, type));
            }

        }
    }


    public AggregateStreamSystemHandlerDescriptor GetAggregateStreamSystemHandlerDescriptor(string applicationId)
    {
        if (_aggregateStreamSystemHandlerDescriptors.TryGetValue(applicationId, out var handlerDescriptor))
        {
            return handlerDescriptor;
        }
        throw new ArgumentException($"[AggregateStreamSystemHandlerDescriptor] not : {applicationId}");
    }

    public IReadOnlyCollection<AggregateStreamSystemHandlerDescriptor> GetAggregateStreamSystemHandlerDescriptors()
    {
        return [.. _aggregateStreamSystemHandlerDescriptors.Values];
    }

    private List<Type> FindAggregateStreamSystemHandlerTypes()
    {
        Type[] baseTypes = [typeof(IAggregateStreamSystemHandler<,>)];
        return _reflectionManager.GetTypes(type => baseTypes.Any(b => type.IsDeriveClassFrom(b)) && type.HasAttribute<AggregateStreamSystemHandlerAttribute>());
    }

    private static Type GetAggregateEventDataType(Type type)
    {
        return type.GetTypeInfo()
            .ImplementedInterfaces
            .Single(r => r.IsGenericType && r.GetGenericTypeDefinition() == typeof(IAggregateStreamSystemHandler<,>))
            .GetGenericArguments()
            .First();
    }

    private static Type GetAggregateSummaryEventDataType(Type type)
    {
        return type.GetTypeInfo()
            .ImplementedInterfaces
            .Single(r => r.IsGenericType && r.GetGenericTypeDefinition() == typeof(IAggregateStreamSystemHandler<,>))
            .GetGenericArguments()
            .Last();
    }
}
